﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Web.Http;
using TinyContactManager.Web.Internal.Data;
using TinyContactManager.Web.Internal.Entities;
using TinyContactManager.Web.Internal.Signaling;
using TinyContactManager.Web.Models;

namespace TinyContactManager.Web.Controllers
{
    public class ContactsController : ApiController
    {
        private readonly IDbContext _dbContext;
        private readonly ContactNotification _notifications;

        public ContactsController(IDbContext dbContext, ContactNotification notifications)
        {
            _dbContext = dbContext;
            _notifications = notifications;
        }

        public IEnumerable<RegistrationsByMonthModel> GetRegistrationsByMonth()
        {
            var registrations = _dbContext.Set<Contact>()
                .Include(x => x.PostalAddress)
                .Include(x => x.Mailings)
                .Where(x => x.Active)
                .ToArray()
                .GroupBy(x => x.DateOfBirth.Month)
                .OrderBy(x => x.Key)
                .Select(x => new RegistrationsByMonthModel(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key), 
                    x.OrderBy(y => y.DateOfBirth.Day)
                    .Select(y => new RegistrationModel(y)).ToArray()))
                .ToArray();
            return registrations;
        }

        [HttpPost]
        public RegistrationModel InsertContact(RegistrationModel model)
        {
            var entity = new Contact();
            UpdateEntityFields(model, entity);
            var dbSet = _dbContext.Set<Contact>();
            dbSet.Add(entity);
            _dbContext.Save();

            var registrationModel = new RegistrationModel(entity);
            _notifications.NotifyRefresh(registrationModel);
            return registrationModel;
        }

        [HttpPut]
        public RegistrationModel UpdateContact(RegistrationModel model)
        {
            var dbSet = _dbContext.Set<Contact>();
            var entity = dbSet.Include(x => x.Mailings).Include(x => x.PostalAddress).FirstOrDefault(x => x.Id == model.Id);
            UpdateEntityFields(model, entity);
            _dbContext.Save();
            var registrationModel = new RegistrationModel(entity);
            _notifications.NotifyRefresh(registrationModel);
            return registrationModel;
        }

        [HttpDelete]
        public void DeleteContact(ContactIdModel contact)
        {
            var dbSet = _dbContext.Set<Contact>();
            var toDelete = dbSet.Find(contact.Id);
            toDelete.Active = false;
            _dbContext.Save();

            var registrationModel = new RegistrationModel(toDelete);
            _notifications.NotifyDelete(registrationModel);
        }

        private static void UpdateEntityFields(RegistrationModel model, Contact entity)
        {
            entity.FirstName = model.FirstName;
            entity.LastName = model.LastName;
            entity.DateOfBirth = DateTime.Parse(model.Birthday);
            entity.Email = model.Email;
            entity.Telephone = model.Phone;
            entity.PostalAddress = entity.PostalAddress ?? new Address();
            entity.PostalAddress.Street1 = model.Street1;
            entity.PostalAddress.Street2 = model.Street2;
            entity.PostalAddress.Postcode = model.Postcode;
            entity.PostalAddress.State = model.State;
            entity.PostalAddress.Suburb = model.Suburb;
        }
    }
}